struct Listener:
    public FrameListener,
    public OIS::KeyListener,
    public OIS::MouseListener

{
    bool frameRenderingQueued(const FrameEvent & evt);
    bool frameStarted(const FrameEvent & evt);
    bool frameEnded(const FrameEvent & evt);

    // ####### OIS #######
    bool mouseMoved     (const OIS::MouseEvent &e);
    bool mousePressed   (const OIS::MouseEvent &e, OIS::MouseButtonID id);
    bool mouseReleased  (const OIS::MouseEvent &e, OIS::MouseButtonID id);
    bool keyPressed     (const OIS::KeyEvent &e);
    bool keyReleased    (const OIS::KeyEvent &e);    
};

    void go();
    void add_col_obj(size_t);
    //void check_collisions();

    ///////////////////////////////
    // ####### initializing #######
    ///////////////////////////////
namespace init
{
    void init();
    void init_bullets();
    void init_laser();
    void init_inputs();
    void init_gorilla();
    void init_resources();

    void init_other();

    void init_procedural();
    void add_debug_gizmo(string name);
    void createBar(Vec2 origin, Vec2 dim, Bar & bar);
    ////////////////////////////////////
    // ####### called at loading #### //
    ////////////////////////////////////
    void make_scene_query();
    void Populate();
    void LoadEntity(string); // only for movables
    void loadlevel(std::string);
    void loadlist();
    void AddPlane();
    void AddLights();
    MaterialPtr create_hover_material(MaterialPtr mat);
    SceneTypeMask GetScMgrType();
    SceneNode * AddLight(string);

    // config file reading
    float    GetFloat   (string _s);
    int      GetInt     (string _s);
    Vec2     GetVect2   (string _s);
    Vec3     GetVect3   (string _s);
    string   GetString  (string _s);
    string   str_vect(Vec3 v)
    { return TO_STR(v.x) + " " + TO_STR(v.y)+ " " + TO_STR(v.z); }
    static string str_quat(Quaternion q)
    { return TO_STR(q.w)+" "+TO_STR(q.x)+" "+TO_STR(q.y)+" "+TO_STR(q.z); }
}

    ///////////////////////////////
    // ####### in game loop #######
    ///////////////////////////////
namespace game_loop
{
    void moveTo(ushort idx, Vec3 dest, float speed = 3.f);

    void setCameraMode(int mode);
    void fire_trace();
    void trigger_pull();
    void trigger_release();
    
    void update_physics(); // in game loop
    void update_recoil();
    void update_bullets();
    void update_laser();
    void update_ui();
    void diagnose();
    // ####### math/interp functions #######
    float recoil(float);
    void recoil_event();
    float smoothstep(float x);
    float smoothstep2(float,float,float);
    float smoothstep_fast(float x);
    float weight_avg(float x, float goal, float slowdown);


    void check_mouse_hover();
    void find_near_objects(Ogre::Vector3 pos, float radius);
}
